]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
StTextureCache: add api to load image to cairo surface
authorRay Strode <rstrode@redhat.com>
Fri, 10 Dec 2010 22:15:39 +0000 (17:15 -0500)
committerRay Strode <rstrode@redhat.com>
Mon, 24 Jan 2011 17:23:11 +0000 (12:23 -0500)
Loading a pixbuf in a way that cairo can use it is a
pretty involved process that involves a lot of code, and pixel
fiddling.

This commit adds the mechanism to StTextureCache so we can reuse
the existing pixbuf handling code there, and also get caching.

https://bugzilla.gnome.org/show_bug.cgi?id=636976

src/st/st-texture-cache.c
src/st/st-texture-cache.h

index c7906ab9c5bb8f02a1b639fbc12d2108b76029d1..52ce02ed0b06130e63c59964cd4bb3ba039c28e9 100644 (file)
@@ -30,6 +30,7 @@
 
 #define CACHE_PREFIX_GICON "gicon:"
 #define CACHE_PREFIX_URI "uri:"
+#define CACHE_PREFIX_URI_FOR_CAIRO "uri-for-cairo:"
 #define CACHE_PREFIX_THUMBNAIL_URI "thumbnail-uri:"
 #define CACHE_PREFIX_RAW_CHECKSUM "raw-checksum:"
 #define CACHE_PREFIX_COMPRESSED_CHECKSUM "compressed-checksum:"
@@ -798,6 +799,27 @@ pixbuf_to_cogl_handle (GdkPixbuf *pixbuf)
                                      gdk_pixbuf_get_pixels (pixbuf));
 }
 
+static cairo_surface_t *
+pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
+{
+  cairo_surface_t *dummy_surface;
+  cairo_pattern_t *pattern;
+  cairo_surface_t *surface;
+  cairo_t *cr;
+
+  dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+
+  cr = cairo_create (dummy_surface);
+  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+  pattern = cairo_get_source (cr);
+  cairo_pattern_get_surface (pattern, &surface);
+  cairo_surface_reference (surface);
+  cairo_destroy (cr);
+  cairo_surface_destroy (dummy_surface);
+
+  return surface;
+}
+
 static GdkPixbuf *
 load_pixbuf_fallback(AsyncTextureLoadData *data)
 {
@@ -1504,6 +1526,45 @@ out:
   return texdata;
 }
 
+static cairo_surface_t *
+st_texture_cache_load_uri_sync_to_cairo_surface (StTextureCache        *cache,
+                                                 StTextureCachePolicy   policy,
+                                                 const gchar           *uri,
+                                                 int                    available_width,
+                                                 int                    available_height,
+                                                 GError               **error)
+{
+  cairo_surface_t *surface;
+  GdkPixbuf *pixbuf;
+  char *key;
+
+  key = g_strconcat (CACHE_PREFIX_URI_FOR_CAIRO, uri, NULL);
+
+  surface = g_hash_table_lookup (cache->priv->keyed_cache, key);
+
+  if (surface == NULL)
+    {
+      pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, error);
+      if (!pixbuf)
+        goto out;
+
+      surface = pixbuf_to_cairo_surface (pixbuf);
+      g_object_unref (pixbuf);
+
+      if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
+        {
+          cairo_surface_reference (surface);
+          g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), surface);
+        }
+    }
+  else
+    cairo_surface_reference (surface);
+
+out:
+  g_free (key);
+  return surface;
+}
+
 /**
  * st_texture_cache_load_uri_sync:
  *
@@ -1582,6 +1643,43 @@ st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
   return texture;
 }
 
+/**
+ * st_texture_cache_load_file_to_cairo_surface:
+ * @cache: A #StTextureCache
+ * @file_path: Path to a file in supported image format
+ *
+ * This function synchronously loads the given file path
+ * into a cairo surface.  On error, a warning is emitted
+ * and %NULL is returned.
+ *
+ * Returns: (transfer full): a new #cairo_surface_t *
+ */
+cairo_surface_t *
+st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
+                                             const gchar    *file_path)
+{
+  cairo_surface_t *surface;
+  GFile *file;
+  char *uri;
+  GError *error = NULL;
+
+  file = g_file_new_for_path (file_path);
+  uri = g_file_get_uri (file);
+
+  surface = st_texture_cache_load_uri_sync_to_cairo_surface (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
+                                                             uri, -1, -1, &error);
+  g_object_unref (file);
+  g_free (uri);
+
+  if (surface == NULL)
+    {
+      g_warning ("Failed to load %s: %s", file_path, error->message);
+      g_clear_error (&error);
+      return NULL;
+    }
+  return surface;
+}
+
 /**
  * st_texture_cache_load_file_simple:
  * @cache: A #StTextureCache
index 4f1a4820a9979c7920f22dba1d4fc3432ca3789b..5f1e7019326e7efe82b8070b683d86d8e249e600 100644 (file)
@@ -119,6 +119,9 @@ ClutterActor *st_texture_cache_load_uri_sync (StTextureCache       *cache,
 CoglHandle    st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
                                                           const gchar    *file_path);
 
+cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
+                                                              const gchar    *file_path);
+
 ClutterActor *st_texture_cache_load_file_simple (StTextureCache *cache,
                                                  const gchar    *file_path);